﻿using Serilog.Parsing;
using System.Diagnostics;
using System.Windows.Forms.VisualStyles;
using WindowsInput;

namespace AutoClickTool.Common
{
    public class WindowInputHelper
    {
        const int WM_SETTEXT = 0x000C;
        private readonly InputSimulator _simulator;
        public WindowInputHelper(InputSimulator simulator)
        {
            this._simulator = simulator;
        }
        /// <summary>
        /// 按下
        /// </summary>
        const uint WM_KEYDOWN = 0x0100;
        /// <summary>
        /// 抬起
        /// </summary>
        const uint WM_KEYUP = 0x0101;
        const int KEYEVENTF_KEYDOWN = 0x0000;
        const int KEYEVENTF_KEYUP = 0x0002;
        /// <summary>
        /// 指定窗口模拟按键松开
        /// </summary>
        /// <param name="targetWindowHandle"></param>
        public WindowInputHelper KeyPressToWindow(Keys key, IntPtr targetWindowHandle)
        {
            KeyDown(key, targetWindowHandle);
            KeyUp(key, targetWindowHandle);
            return this;
        }
        /// <summary>
        /// 指定窗口抬起按键
        /// </summary>
        /// <param name="key"></param>
        /// <param name="targetWindowHandle"></param>
        public WindowInputHelper KeyUpToWindow(Keys key, IntPtr targetWindowHandle)
        {
            Thread.Sleep(100);
            WindowsApiHelper.SendMessage(targetWindowHandle, WM_KEYUP, (IntPtr)key, IntPtr.Zero);
            return this;
        }
        /// <summary>
        /// 指定窗口放下按键
        /// </summary>
        /// <param name="key"></param>
        /// <param name="targetWindowHandle"></param>
        public WindowInputHelper KeyDownToWindow(Keys key, IntPtr targetWindowHandle)
        {
            Thread.Sleep(100);
            WindowsApiHelper.SendMessage(targetWindowHandle, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);
            return this;
        }
        /// <summary>
        /// 指定窗口点击鼠标
        /// </summary>
        /// <param name="key"></param>
        /// <param name="targetWindowHandle"></param>
        /// <returns></returns>
        public WindowInputHelper MousePressToWindow(Keys key, IntPtr targetWindowHandle)
        {
            KeyDownToWindow(key, targetWindowHandle);
            KeyUpToWindow(key, targetWindowHandle);
            return this;
        }
        /// <summary>
        /// 指定窗口鼠标抬起
        /// </summary>
        /// <param name="key"></param>
        /// <param name="targetWindowHandle"></param>
        /// <returns></returns>
        public WindowInputHelper MouseUpToWindow(Keys key, IntPtr targetWindowHandle)
        {
            Thread.Sleep(100);
            return KeyUp(key, targetWindowHandle);
        }
        /// <summary>
        /// 指定窗口鼠标按下
        /// </summary>
        /// <param name="key"></param>
        /// <param name="targetWindowHandle"></param>
        /// <returns></returns>
        public WindowInputHelper MouseDownToWindow(Keys key, IntPtr targetWindowHandle)
        {
            Thread.Sleep(100);
            return KeyDown(key, targetWindowHandle);
        }

        /// <summary>
        /// 全局模拟按键
        /// </summary>
        /// <param name="targetWindowHandle"></param>
        public WindowInputHelper KeyPress(Keys key, IntPtr? targetWindowHandle = null)
        {
            if (targetWindowHandle == null)
            {
                KeyDown(key);
                KeyUp(key);
            }
            else
            {
                KeyPressToWindow(key, targetWindowHandle.Value);
            }
            return this;
        }
        /// <summary>
        /// 全局模拟抬起按键
        /// </summary>
        /// <param name="key"></param>
        /// <param name="targetWindowHandle"></param>
        public WindowInputHelper KeyUp(Keys key, IntPtr? targetWindowHandle = null)
        {
            if (targetWindowHandle == null)
            {
                int virtualKeyCode = (int)key;
                WindowsApiHelper.keybd_event((byte)virtualKeyCode, 0, KEYEVENTF_KEYUP, IntPtr.Zero);
            }
            else
            {
                KeyUpToWindow(key, targetWindowHandle.Value);
            }

            return this;
        }
        /// <summary>
        /// 全局模拟放下按键
        /// </summary>
        /// <param name="key"></param>
        /// <param name="targetWindowHandle"></param>
        public WindowInputHelper KeyDown(Keys key, IntPtr? targetWindowHandle = null)
        {
            if (targetWindowHandle == null)
            {
                int virtualKeyCode = (int)key;
                WindowsApiHelper.keybd_event((byte)virtualKeyCode, 0, KEYEVENTF_KEYDOWN, IntPtr.Zero);
            }
            else
            {
                KeyDownToWindow(key, targetWindowHandle.Value);
            }

            return this;
        }

        /// <summary>
        /// 全局模拟点击鼠标
        /// </summary>
        /// <param name="key"></param>
        /// <param name="targetWindowHandle"></param>
        /// <returns></returns>
        public WindowInputHelper MousePress(Keys key, IntPtr? targetWindowHandle = null)
        {
            if (targetWindowHandle == null)
            {
                MouseDown(key);
                MouseUp(key);
            }
            else
            {
                MousePressToWindow(key, targetWindowHandle.Value);
            }
            return this;
        }
        /// <summary>
        /// 全局模拟鼠标抬起
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public WindowInputHelper MouseUp(Keys key, IntPtr? targetWindowHandle = null)
        {
            if (targetWindowHandle == null)
            {
                switch (key)
                {
                    case Keys.LButton:
                        WindowsApiHelper.mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
                        break;
                    case Keys.MButton:
                        WindowsApiHelper.mouse_event(MouseEventFlag.MiddleUp, 0, 0, 0, UIntPtr.Zero);
                        break;
                    case Keys.RButton:
                        WindowsApiHelper.mouse_event(MouseEventFlag.RightUp, 0, 0, 0, UIntPtr.Zero);
                        break;
                }
            }
            else
            {
                MouseUpToWindow(key, targetWindowHandle.Value);
            }
            return this;
        }
        /// <summary>
        /// 全局模拟鼠标按下
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public WindowInputHelper MouseDown(Keys key, IntPtr? targetWindowHandle = null)
        {
            if (targetWindowHandle == null)
            {
                switch (key)
                {
                    case Keys.LButton:
                        WindowsApiHelper.mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
                        break;
                    case Keys.MButton:
                        WindowsApiHelper.mouse_event(MouseEventFlag.MiddleDown, 0, 0, 0, UIntPtr.Zero);
                        break;
                    case Keys.RButton:
                        WindowsApiHelper.mouse_event(MouseEventFlag.RightDown, 0, 0, 0, UIntPtr.Zero);
                        break;
                }
            }
            else
            {
                MouseDownToWindow(key, targetWindowHandle.Value);
            }

            return this;
        }
        const int WM_PASTE = 0x0302;
        public WindowInputHelper SendText(string text, IntPtr? targetWindowHandle = null)
        {
            Clipboard.SetText(text);
            if (targetWindowHandle.HasValue)
            {
                // 设置指定窗口为前台窗口，即给予焦点
                WindowsApiHelper.SetForegroundWindow(targetWindowHandle.Value);
                // 等待一段时间以确保窗口有足够的时间获取焦点
                Thread.Sleep(1000);
            }
            SendKeys.SendWait("^v");
            return this;
        }
        /// <summary>`
        /// 休眠时间
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public WindowInputHelper Sleep(int time)
        {
            Thread.Sleep(time);
            return this;
        }
    }
}
